﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Data;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq.Expressions;
using System.Reflection;
using System.ComponentModel;

namespace Utility
{
    // các hàm select , insert , update , delete dùng chung cho toàn bộ project
    public class LinqUtility<T> where T : class
    {
        // Tạo đối tượng chung của database
        QuanLyPhongHocDataContext context = new QuanLyPhongHocDataContext();

        // Lấy toàn bộ dữ liệu của 1 bảng ko có điều kiện ( T : là một bảng nào đó bất kì )
        public List<T> GetAll()
        {
            return GetTable.Cast<T>().ToList();
        }

        // Lấy toàn bộ dữ liệu của 1 bảng có điều kiện ( T : là một bảng nào đó bất kì , Func<T, bool> exp :  là điều kiện , biểu thức linq )
        public List<T> Find(Func<T, bool> exp)
        {
            return GetTable.Cast<T>().Where(exp).ToList();
        }

        // Lấy một dòng dữ liệu của 1 bảng ko có điều kiện ( T : là một bảng nào đó bất kì , Func<T, bool> exp :  là điều kiện , biểu thức linq  )
        public T GetById(Func<T, bool> exp)
        {
            return GetTable.Cast<T>().Single(exp);
        }

        // insert dữ liệu của 1 bảng
        public void Insert(T entity)
        {

            context.GetTable<T>().InsertOnSubmit(entity);
            context.SubmitChanges();

        }

        // update dữ liệu của 1 bảng
        public void Update(T item)
        {
            var store = new QuanLyPhongHocDataContext();
            var table = store.GetTable<T>();
            table.Attach(item);
            store.Refresh(RefreshMode.KeepCurrentValues, item);
            store.SubmitChanges();
        }

        // xóa dữ liệu của 1 bảng
        public void Delete(T item)
        {
            var store = new QuanLyPhongHocDataContext();
            var table = store.GetTable<T>();
            table.Attach(item);
            table.DeleteOnSubmit(item);
            store.Refresh(RefreshMode.KeepCurrentValues, item);
            store.SubmitChanges();
        }

        public void UpdateNew(T item) 
        {
            try
            {
                // create a new instance of the object
                Object newObj = Activator.CreateInstance(typeof(T), new object[0]);

                PropertyDescriptorCollection originalProps = TypeDescriptor.GetProperties(item);

                // set the new object to match the passed in object
                foreach (PropertyDescriptor currentProp in originalProps)
                {
                    if (currentProp.Attributes[typeof(System.Data.Linq.Mapping.ColumnAttribute)] !=null)
                    {
                        object val = currentProp.GetValue(item);
                        currentProp.SetValue(newObj, val);
                    }
                }

                // attach the new object to a new data context and
                // call submit changes on the context
                using (QuanLyPhongHocDataContext context = new QuanLyPhongHocDataContext())
                {
                    var table = context.GetTable<T>();
                    table.Attach((T)newObj, true);
                    context.SubmitChanges();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        private Table<T> GetTable
        {
            get { return context.GetTable<T>(); }
        }

    }
}
